
#include "type.h"
#include "sim_timer_config.h"

#ifndef SIM_TIMER_MAX
#error "SIM_TIMER_MAX NOT HAVE A CONFIG VALUE"
#endif

typedef struct {
	volatile uint16_t count;
	volatile uint16_t timeout;
	volatile bool_t running;
	volatile bool_t overtime;
} SIM_TIMER_STRUCT;

static volatile SIM_TIMER_STRUCT SIM_TIMERS[SIM_TIMER_MAX];

void sim_timer_init(void)
{
	volatile uint8_t i;
	for (i = 0; i < SIM_TIMER_MAX; i++) {
		SIM_TIMERS[i].count = 0;
		SIM_TIMERS[i].timeout = 0;
		SIM_TIMERS[i].running = false;
		SIM_TIMERS[i].overtime = false;
	}
}

void sim_timer_tick_hander(uint16_t ticks)
{
	volatile uint8_t i;
	uint16_t ticks_temp;
	for (i = 0; i < SIM_TIMER_MAX; i++) {
		if ((SIM_TIMERS[i].running == true)&&(SIM_TIMERS[i].overtime == false)) {
			if(ticks < SIM_TIMERS[i].count){
				SIM_TIMERS[i].count -= ticks;
			}
			else{
				SIM_TIMERS[i].count = SIM_TIMERS[i].timeout;
				SIM_TIMERS[i].overtime = true;
				ticks_temp = ticks;
				while(ticks_temp >= SIM_TIMERS[i].timeout){
					ticks_temp -= SIM_TIMERS[i].timeout;
				}
				if(ticks_temp < SIM_TIMERS[i].count){
					SIM_TIMERS[i].count -= ticks_temp;
				}
				else{	//ticks >= count & ticks < timeout
					//count = count + timeout - ticks;
					ticks_temp = SIM_TIMERS[i].timeout - ticks_temp;
					SIM_TIMERS[i].count = SIM_TIMERS[i].count + ticks_temp;
				}
			}
		}
	}
}

bool_t sim_timer_check_running(uint16_t sim_timer_num)
{
	if(sim_timer_num < SIM_TIMER_MAX){
		return SIM_TIMERS[sim_timer_num].running;
	}
	else{
		return false;
	}
}

bool_t sim_timer_check_overtime(uint16_t sim_timer_num)
{
	bool_t ret;
	if(sim_timer_num < SIM_TIMER_MAX){
		ret =  SIM_TIMERS[sim_timer_num].overtime;
		SIM_TIMERS[sim_timer_num].overtime = false;
		return ret;
	}
	else{
		return false;
	}
}

void sim_timer_start(uint16_t sim_timer_num)
{
	if(sim_timer_num < SIM_TIMER_MAX){
		SIM_TIMERS[sim_timer_num].running = true;
	}  
}

void sim_timer_stop(uint16_t sim_timer_num)
{
	if(sim_timer_num < SIM_TIMER_MAX){
		SIM_TIMERS[sim_timer_num].running = false;
	}  
}

void sim_timer_restart(uint16_t sim_timer_num)
{ 
	if(sim_timer_num < SIM_TIMER_MAX){
		SIM_TIMERS[sim_timer_num].count = SIM_TIMERS[sim_timer_num].timeout;
		SIM_TIMERS[sim_timer_num].running = true;
	}
}

void sim_timer_set_timeout(uint16_t sim_timer_num, uint16_t set_timeout)
{
	if(sim_timer_num < SIM_TIMER_MAX){
		SIM_TIMERS[sim_timer_num].timeout = set_timeout;
	}
}
